Function.RegisterNamespace("Test.System.IO");

[Fixture]
Test.System.IO.Directory=function(){
    [Fixture]
    function Directory(){
        [Fact]
        function InitializesStrategyManager(){
            var expected=System.Script.Strategy.StrategyManager;
        
            var actual=System.IO.Directory.Strategies;
            
            Assert.True(Object.IsType(expected,actual));
        }
    }
        
    [Fixture]
    function Exists(){
        [Fact]
        function ThrowsIfPathIsOmitted(){
            var expected="System.IO.Directory.Exists: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.Exists();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsUndefined(){
            var expected="System.IO.Directory.Exists: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.Exists(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsNull(){
            var expected="System.IO.Directory.Exists: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.Exists(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfPathIsNotConvertibleToString(){
            var expected="System.IO.Directory.Exists: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.Exists({toString:null});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsToStringMethodOnPath(){
            var target={toString:function(){
                actual=true;
                return "";
            }};
            var actual=false;
            
            System.IO.Directory.Exists(target);
            
            Assert.True(actual);
        }

        [Fact]
        function GetsStrategyFromStrategyManager(){
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                actual=true;
                return {Exists:function(){}}
            };
            var actual=false;
            
            System.IO.Directory.Exists("");
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsExistsMethodOnStrategy(){
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {Exists:function(){
                    actual=true;
                }}
            };
            var actual=false;
            
            System.IO.Directory.Exists("");
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsValueOfExistsMethodFromStrategy(){
            var expected="expected";
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {Exists:function(){
                    return expected;
                }}
            };
            
            var actual=System.IO.Directory.Exists("");
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfStrategyManagerGetMethodThrows(){
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error();
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.Exists("");
            });            
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyManagerGetMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.Directory.Exists: {0}",target);
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.Exists("");
            });
            System.IO.Directory.Strategies.Get=targetGet;

            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfExistsMethodThrows(){
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {Exists:function(){
                    throw new Error();
                }}
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.Exists("");
            });
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyExistsMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.Directory.Exists: {0}",target);
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.Exists("");
            });
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }
    }

    [Fixture]
    function GetFiles(){
        [Fact]
        function ThrowsIfPathIsOmitted(){
            var expected="System.IO.Directory.GetFiles: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.GetFiles();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsUndefined(){
            var expected="System.IO.Directory.GetFiles: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.GetFiles(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsNull(){
            var expected="System.IO.Directory.GetFiles: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.GetFiles(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfPathIsNotConvertibleToString(){
            var expected="System.IO.Directory.GetFiles: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.GetFiles({toString:null});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsToStringMethodOnPath(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return false;
            };
            var target={toString:function(){
                actual=true;
                return "";
            }};
            var actual=false;

            System.IO.Directory.GetFiles(target);
            System.IO.Directory.Exists=targetExists;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsDirectoryExistsMethod(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                actual=true;
                return false;
            };
            var actual=false;

            System.IO.Directory.GetFiles("");
            System.IO.Directory.Exists=targetExists;
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsEmptyArrayIfDirectoryExistsReturnsFalse(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return false;
            };
            
            var actual=System.IO.Directory.GetFiles("");
            System.IO.Directory.Exists=targetExists;
            
            Assert.True(Object.IsType(Array,actual));
        }
        
        [Fact]
        function GetsStrategyFromStrategyManager(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                actual=true;
                return {GetFiles:function(){}}
            };
            var actual=false;
            
            System.IO.Directory.GetFiles("");
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsGetFilesMethodOnStrategy(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {GetFiles:function(){
                    actual=true;
                }}
            };
            var actual=false;
            
            System.IO.Directory.GetFiles("");
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function SortsFilesReturnedFromStrategy(){
            var expected=["expected1","ExPected2","expEcteD3"];
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {GetFiles:function(){
                    return Array.Shuffle(expected);
                }}
            };
            
            var actual=System.IO.Directory.GetFiles("");
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ReturnsValueOfGetFilesMethodFromStrategy(){
            var expected="expected";
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {GetFiles:function(){
                    return expected;
                }}
            };
            
            var actual=System.IO.Directory.GetFiles("");
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfStrategyManagerGetMethodThrows(){
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error();
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.GetFiles("");
            });            
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyManagerGetMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.Directory.GetFiles: {0}",target);
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.GetFiles("");
            });
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;

            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfGetFilesMethodThrows(){
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {GetFiles:function(){
                    throw new Error();
                }}
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.GetFiles("");
            });
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyGetFilesMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.Directory.GetFiles: {0}",target);
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.GetFiles("");
            });
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }
    }

    [Fixture]
    function GetDirectories(){
        [Fact]
        function ThrowsIfPathIsOmitted(){
            var expected="System.IO.Directory.GetDirectories: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.GetDirectories();
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsUndefined(){
            var expected="System.IO.Directory.GetDirectories: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.GetDirectories(undefined);
            });
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfPathIsNull(){
            var expected="System.IO.Directory.GetDirectories: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.GetDirectories(null);
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfPathIsNotConvertibleToString(){
            var expected="System.IO.Directory.GetDirectories: 'path' must be convertible to String.";
            
            var actual=Record.Exception(function(){
                System.IO.Directory.GetDirectories({toString:null});
            });
            
            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function CallsToStringMethodOnPath(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return false;
            };
            var target={toString:function(){
                actual=true;
                return "";
            }};
            var actual=false;

            System.IO.Directory.GetDirectories(target);
            System.IO.Directory.Exists=targetExists;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsDirectoryExistsMethod(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                actual=true;
                return false;
            };
            var actual=false;

            System.IO.Directory.GetDirectories("");
            System.IO.Directory.Exists=targetExists;
            
            Assert.True(actual);
        }

        [Fact]
        function ReturnsEmptyArrayIfDirectoryExistsReturnsFalse(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return false;
            };
            
            var actual=System.IO.Directory.GetDirectories("");
            System.IO.Directory.Exists=targetExists;
            
            Assert.True(Object.IsType(Array,actual));
        }
        
        [Fact]
        function GetsStrategyFromStrategyManager(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                actual=true;
                return {GetDirectories:function(){}}
            };
            var actual=false;
            
            System.IO.Directory.GetDirectories("");
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function CallsGetDirectoriesMethodOnStrategy(){
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {GetDirectories:function(){
                    actual=true;
                }}
            };
            var actual=false;
            
            System.IO.Directory.GetDirectories("");
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.True(actual);
        }

        [Fact]
        function SortsDirectoriesReturnedFromStrategy(){
            var expected=["expected1","ExPected2","expEcteD3"];
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {GetDirectories:function(){
                    return Array.Shuffle(expected);
                }}
            };
            
            var actual=System.IO.Directory.GetDirectories("");
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ReturnsValueOfGetDirectoriesMethodFromStrategy(){
            var expected="expected";
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {GetDirectories:function(){
                    return expected;
                }}
            };
            
            var actual=System.IO.Directory.GetDirectories("");
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }

        [Fact]
        function ThrowsIfStrategyManagerGetMethodThrows(){
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error();
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.GetDirectories("");
            });            
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyManagerGetMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.Directory.GetDirectories: {0}",target);
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.GetDirectories("");
            });
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;

            Assert.Equal(expected,actual);
        }
        
        [Fact]
        function ThrowsIfGetDirectoriesMethodThrows(){
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                return {GetDirectories:function(){
                    throw new Error();
                }}
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.GetDirectories("");
            });
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.NotNull(actual);
        }

        [Fact]
        function ThrowsWhatStrategyGetDirectoriesMethodThrows(){
            var target="expected";
            var expected=String.Format("System.IO.Directory.GetDirectories: {0}",target);
            var targetExists=System.IO.Directory.Exists;
            System.IO.Directory.Exists=function(){
                return true;
            };
            var targetGet=System.IO.Directory.Strategies.Get;
            System.IO.Directory.Strategies.Get=function(){
                throw new Error(target);
            };

            var actual=Record.Exception(function(){
                System.IO.Directory.GetDirectories("");
            });
            System.IO.Directory.Exists=targetExists;
            System.IO.Directory.Strategies.Get=targetGet;
            
            Assert.Equal(expected,actual);
        }
    }
}